<?php

/**
 * @classname 整站公共类
 * @classaccess private
 * @decription 整站程序的公共类
 * @author 张旭刚
 * @updateTime 2019年09月29日
 * @errorCode 100001|鉴权证书不能为空
 */

namespace common\controllers;

use Yii;
use yii\web\Controller;
use yii\helpers\Json;
use common\models\Settings;
use yii\web\Response;
use yii\web\Session;
use PHPMailer;
use common\models\Mails;

class CommonController extends Controller {

    private $logPath;
    protected $headers;
    protected $guid;
    protected $cache;
    protected $redis;

    public function __construct($id, $module, $config = array()) {
        parent::__construct($id, $module, $config);
        $this->getLogPath();
        $this->cache = Yii::$app->cache;
        $this->redis = Yii::$app->redis;
    }
    
    /**
     * 获取当前URL（去除域名部分）
     * @return type
     */
    protected function getUrl(){
        $url = Yii::$app->request->getUrl();
        $urls = explode('?', $url);
        return $urls[0];
    }

    /**
     * 数据返回方式
     */
    protected function renderJson($data) {
        $type = 'json';
        if (is_array($data)) {
            $type = 'array';
            $data = Json::encode($data);
        }
        die($data);
    }

    /**
     * 获取设置
     */
    protected function setting($key, $field = 'setValue') {
        $cacheKey = 'settings';
        $data = unserialize(Yii::$app->redis->hget($cacheKey, $key));
        if(empty($data)){
            $data = Settings::find()->where(['setTag' => $key])->asArray()->one();
            if (empty($data)) {
                return false;
            }
            Yii::$app->redis->hset($cacheKey, $key, serialize($data));
        }
        return $data[$field];
    }

    /**
     * 获得Log目录位置
     */
    private function getLogPath() {
        $this->logPath = $this->setting('log_path');
        if (!file_exists($this->logPath)) {
            @mkdir($this->logPath, 777);
        }
    }

    /**
     * 产生Log
     */
    protected function setLog($name, $content, $showSystemParam = false) {
        $d = ['time' => date('Y-m-d H:i:s'), 'data' => $content];
        if($showSystemParam){
            $d['sysParam'] = ['post' => Yii::$app->request->post(), 'get' => Yii::$app->request->get(), 'input' => file_get_contents('php://input'), 'serverInfo' => $_SERVER];
        }
        $file = $this->logPath . $name . '.log';
        $line = "\n\n-------------------------------------------------------分割线----------------------------------------------------------\n\n\n";
        $log = print_r($d, 1). $line;
        return @file_put_contents($file, $log, FILE_APPEND);
    }

    /**
     * 产生重复的唯一编号
     */
    protected function getGuid($prefix = '') {
        if (function_exists('com_create_guid')) {
            $guid = com_create_guid();
        } else {
            $rnd = mt_srand((double) microtime() * 10000); //optional for php 4.2.0 and up.
            $charid = strtoupper(md5(uniqid(rand(), true)));
            $hyphen = chr(45); // "-"
            $guid = substr($charid, 0, 8) . $hyphen . substr($charid, 8, 4) . $hyphen . substr($charid, 12, 4) . $hyphen . substr($charid, 16, 4) . $hyphen . substr($charid, 20, 12);
        }
        return $guid;
    }

    /**
     * 生成二维码
     */
    protected function qrcode($text, $filename, $data = []) {
        if(empty($text)){
            return false;
        }
        $data['text'] = $text;
        $codeUrl = $this->setting('qrcode_url');
        foreach((array)$data as $k => $v){
            $d[] = $k . '=' . $v;
        }
        $codeUrl .= implode('&', $d);
        $img = file_get_contents($codeUrl);
        $savePath = $this->setting('save_qrcode_path');
        if(file_exists($savePath)){
            @mkdir($savePath);
        }
        file_put_contents($savePath.'/'.$filename, $img);
        $url = $this->setting('qrcode_domain').'/'.$filename;
        return $url;
    }
    
    /**
     * sha1
     */
    protected function sha1($str, $salt = ''){
        return empty($salt) ? sha1($str, false) : sha1($salt.'_'.$str.'_'.$salt);
    }
    
    /**
     * sha256
     * @param string $baseStr
     * @param string $salt
     * @param bool $rawOutput
     * @return string
     */
    protected function sha256($baseStr, $salt = '', $rawOutput = false){
        if (!is_scalar($baseStr)) {
            return false;
        }
        $str = $salt == '' ? $baseStr : $salt.'_'.$baseStr.'_'.$salt;
        $sha256 = hash('sha256', $str, $rawOutput);
        return $sha256;
    }
    
    /**
     * 计算月份的天数
     * @return type
     */
    protected function getChangeDay($year, $month){
        if(in_array($month, [1,3,5,7,8,10,12])){
            return 31;
        }elseif(in_array($month, [4,6,9,11])){
            return 30;
        }else{
            return ($year % 4 == 0 && $year % 400 != 0) ? 29 : 28;
        }
    }
    
    /**
     * 发送模板消息
     */
    protected function sendTempMsg($tmpId, $data, $url, $openId){
        //获取接口调用Token
        //根据模板编号，组装消息
        //调用接口发出
        $d = ["touser" => $openId, "template_id" => $tmpId, "url" => $url, "data" => $data];
        $listKey = $this->setting('template_message_queque_key');
        return $this->redis->lpush($listKey, serialize($d));
    }
    
    /**
     * 根据配置发送模板消息
     * @param type $configKey
     * @param type $openId
     * @param type $data
     * @return type
     */
    protected function sendTemplateMsg($configKey, $openId, $data){
        if(empty($openId)){return ['result' => false, 'msg' => '通知消息因不知道发送给谁而发送失败'];}
        $config = $this->setting($configKey);
        if(empty($config)){return ['result' => false, 'msg' => '通知消息因发送配置未找到而发送失败'];}
        $configs = explode('|', $this->setting($configKey));
        $templateId = $configs[0];
        $url = $configs[1];
        $varTemp = explode(',', $configs[2]);
        $d = [];
        foreach((array)$varTemp as $v){
            if(!isset($data[$v])){return ['result' => false, 'msg' => '通知消息因消息变量“'.$v.'”未设置而发送失败'];}
            $d[$v] = $data[$v];
        }
        $params = ["touser" => $openId, "template_id" => $templateId, "url" => $url, "data" => $d];
        Yii::$app->wx->sendMessage($params);
        return ['result' => true, 'msg' => '通知发送成功'];
    }
    
    protected function password($password, $passwordKey = ''){
        if($passwordKey == ''){
            $passwordKey = $this->getGuid('pwd_');
        }
        $password = $this->sha256($password, $passwordKey);
        return ['passwordKey' => $passwordKey, 'password' => $password];
    }
    
    /**
     * 生成验证码
     */
    protected function getCaptcha($type = 'all') {
        $cacheKey = 'captcha_'.$this->guid;
        $this->setImgHttpHeaders();
        Yii::$app->response->format = Response::FORMAT_RAW;
        //1.生成一张底图（width:100;height:30）
        $image = imagecreatetruecolor(100, 30);
        //画笔着色
        $bgcolor = imagecolorallocate($image, 255, 255, 255);
        //将底图的着色
        imagefill($image, 0, 0, $bgcolor);
        $len = $this->setting('api_img_verify_code_number');
        $captch_code = $this->createCode($len, $type);
        foreach ($captch_code as $code_key => $code_char) {
            $i = $code_key;
            $fontsize = 6;
            $fontcolor = imagecolorallocate($image, rand(20, 100), rand(30, 100), rand(10, 200));
            $x = ($i * 100 / $len) + rand(5, 10);
            $y = rand(5, 10);
            imagestring($image, $fontsize, $x, $y, $code_char, $fontcolor);
        }
        $code = implode('', $captch_code);
        $this->cache->set($cacheKey, $code);
        //添加干扰点
        for ($i = 0; $i < 100; $i++) {
            $pointcolor = imagecolorallocate($image, rand(50, 200), rand(50, 200), rand(50, 200));
            imagesetpixel($image, rand(0, 100), rand(0, 30), $pointcolor);
        }
        //添加干扰线
        for ($i = 0; $i < 3; $i++) {
            $linecolor = imagecolorallocate($image, rand(80, 200), rand(80, 200), rand(80, 200));
            imageline($image, rand(5, 95), rand(5, 25), rand(5, 95), rand(5, 25), $linecolor);
        }
        ob_start();
        imagepng($image);
        imagedestroy($image);
        $image_data = ob_get_contents();
        ob_end_clean();
        $image_data_base64 = 'data:image/png;base64,' . base64_encode($image_data);
        $imgs = ['img' => $image_data_base64, 'code' => $code];
        return $imgs;
    }
    
    /**
     * 设置图片头
     */
    protected function setImgHttpHeaders() {
        Yii::$app->getResponse()->getHeaders()
                ->set('Pragma', 'public')
                ->set('Expires', '0')
                ->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
                ->set('Content-Transfer-Encoding', 'binary');
        // ->set('Content-type', 'image/png');
    }

    /**
     * 生成随机数
     */
    protected function createCode($len, $type = 'all') {
        $captch_code = [];
        //随机生成四个数字
        if ($type == 'all') {
            $str = "abcdefghkmnpwsert123456789";
        } elseif ($type == 'number') {
            $str = '0123456789';
        } elseif ($type == 'letter') {
            $str = 'abcdefghkmnpwsert';
        }
        for ($i = 0; $i < $len; $i++) {
            //给出一个字符串，用于生成随机验证码
            $rand = rand(0, strlen($str) - 1);
            $fontcontent = $str[$rand]; //substr($str,rand(0,strlen($str)-1),1);//每次截取一个字符
            $captch_code[] = $fontcontent; //拼接
        }
        return $captch_code;
    }

    protected function sendSms ($mobile, $content) {
        
    }
}
